<?php

declare(strict_types=1);

namespace DreamCat\ObjectOrm;

use DreamCat\Array2Class\Array2ClassInterface;
use Dreamcat\Class2Array\JsonValueFixer;
use Psr\Container\ContainerInterface;
use RuntimeException;
use stdClass;

/**
 * orm转换器
 * @author vijay
 */
class ObjectOrm implements OrmInterface
{
    /** @var JsonValueFixer 转数组的对象 */
    private JsonValueFixer $jsonValueFixer;
    /** @var Array2ClassInterface 转对象的接口 */
    private Array2ClassInterface $array2Class;
    public function __construct(private ContainerInterface $container) {
    }

    /**
     * @return ContainerInterface
     */
    public function getContainer(): ContainerInterface
    {
        return $this->container;
    }

    /**
     * @param ContainerInterface $container
     */
    public function setContainer(ContainerInterface $container): void
    {
        $this->container = $container;
    }

    /**
     * @return JsonValueFixer
     */
    public function getJsonValueFixer(): JsonValueFixer
    {
        if (!isset($this->jsonValueFixer)) {
            $this->jsonValueFixer = new Class2Array($this->container);
        }
        return $this->jsonValueFixer;
    }

    /**
     * @param JsonValueFixer $jsonValueFixer
     */
    public function setJsonValueFixer(JsonValueFixer $jsonValueFixer): void
    {
        $this->jsonValueFixer = $jsonValueFixer;
    }

    /**
     * @return Array2ClassInterface
     */
    public function getArray2Class(): Array2ClassInterface
    {
        if (!isset($this->array2Class)) {
            $this->array2Class = new Array2Class($this->container);
        }
        return $this->array2Class;
    }

    /**
     * @param Array2ClassInterface $array2Class
     */
    public function setArray2Class(Array2ClassInterface $array2Class): void
    {
        $this->array2Class = $array2Class;
    }

    /**
     * @inheritDoc
     */
    public function toDatabaseArray(object $modelObj): array
    {
        return $this->getJsonValueFixer()->fixValue($modelObj);
    }

    /**
     * @inheritDoc
     */
    public function toModel(array|stdClass $model, string $modelType): object
    {
        if (!class_exists($modelType)) {
                throw new RuntimeException("指定的模型类 {$modelType} 不存在");
        }
        if (!is_array($model)) {
            $model = (array)$model;
        }
        return $this->getArray2Class()->convert($model, $modelType);
    }
}

# end of file
